package BusinessLogic;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Edwin, Cristian
 */
public class RDF_XML_Reader {

    List<NodeRDF> nodeListRDF;
    List<LinkRDF> linkListRDF;
    List<Node> nodeListXML;
    RDF_XML_Transformer rdfTransformer;
    List<ChildContained> childsContained;

    public RDF_XML_Reader() {
        nodeListRDF = new ArrayList();
        linkListRDF = new ArrayList();
        nodeListXML = new ArrayList();
        rdfTransformer = new RDF_XML_Transformer();
    }

    public void Read(String pathFile, String inputFileName) throws ParserConfigurationException, SAXException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document;
        try {
            document = builder.parse(new File(inputFileName));
            ProcessRootElement(document);

            String jsonNodes = "\"nodes\":" + rdfTransformer.GetJsonTransformation(nodeListRDF);
            String jsonLinks = "\"links\":" + rdfTransformer.GetJsonTransformation(linkListRDF);

            String[] fileNameSplit = inputFileName.split(".");
            String resultToSave = "{" + jsonNodes + "," + jsonLinks + ",\"literals\":{}}";
            rdfTransformer.SaveJsonTransformation(resultToSave, pathFile + "json\\result.json");
        } catch (IOException ex) {
            Logger.getLogger(RDF_XML_Reader.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void ProcessRootElement(Document document) {
        if (document != null) {
            Element rootElement = document.getDocumentElement();
            if (rootElement != null) {
                String name = rootElement.getNodeName();
                String[] nameSplit = name.split(":");

                if (nameSplit.length >= 2 && nameSplit[0].toLowerCase().equals("rdf")) {
                    System.out.println("Nodos: " + nameSplit[1] + " - " + nameSplit[1]);
                    nodeListRDF.add(new NodeRDF(nameSplit[1], nameSplit[1], "uri"));
                }
                ProcessNodeElements(rootElement);
                ProcessNodeElementsLinks(rootElement);
            }
        }
    }

    public void ProcessNodeElements(Element rootElement) {
        NodeList childs = rootElement.getChildNodes();
        for (int i = 0; i < childs.getLength(); i++) {
            Node aChild = childs.item(i);
            NamedNodeMap childAttributes = aChild.getAttributes();
            if (childAttributes != null && childAttributes.getLength() > 0) {
                for (int j = 0; j < childAttributes.getLength(); j++) {
                    String name = childAttributes.item(j).getNodeName();
                    String value = childAttributes.item(j).getNodeValue();
                    String[] nameSplit = name.split(":");

                    if (nameSplit.length >= 2 && nameSplit[0].toLowerCase().equals("rdf")) {
                        System.out.println("Nodos: " + nameSplit[1] + " - " + value);
                        nodeListRDF.add(new NodeRDF(value, value, "uri"));
                        nodeListXML.add(aChild);
                    }
                }
            }
        }
    }

    public void ProcessNodeElementsLinks(Element rootElement) {
        NodeList childs = rootElement.getElementsByTagName("*");
        for (int i = 0; i < childs.getLength(); i++) {
            Node aParent = childs.item(i).getParentNode();
            Node aChild = childs.item(i);
            String nameLink = "";

            NamedNodeMap childAttributes = aChild.getAttributes();
            if (childAttributes != null && childAttributes.getLength() > 0) {
                for (int j = 0; j < childAttributes.getLength(); j++) {
                    String name = childAttributes.item(j).getNodeName();
                    String value = childAttributes.item(j).getNodeValue();
                    String[] nameSplit = name.split(":");

                    if (nameSplit.length >= 2 && nameSplit[0].toLowerCase().equals("rdf")) {
                        nameLink = value;
                    }
                }
            }

            //Procesar buscando dentro de todos los nodos detectados (excepto el principal/root)
            //Si alguno se comporta como hijo de los otros.
            if (nodeListXML.contains(aChild) && aParent != null) {
                ChildContained isChildContained = VerifyIsChildContained(aChild, childs, nameLink);
                
                if(isChildContained != null){
                    if (isChildContained.isContained()) {
                        System.out.println("Enlaces: " + (nodeListXML.indexOf(isChildContained.getParent()) + 1) + " - " + (nodeListXML.indexOf(aChild) + 1) + "-" + nameLink + "-" + 10);
                        linkListRDF.add(new LinkRDF(nodeListXML.indexOf(isChildContained.getParent()) + 1, nodeListXML.indexOf(aChild) + 1, nameLink, 10));
                    } else {
                        System.out.println("Enlaces: " + 0 + " - " + (nodeListXML.indexOf(aChild) + 1) + "-" + nameLink + "-" + 10);
                        linkListRDF.add(new LinkRDF(0, nodeListXML.indexOf(aChild) + 1, nameLink, 10));
                    }
                }
            }
        }
    }

    public ChildContained VerifyIsChildContained(Node childToFind, NodeList childsToCompare, String value) {
        for (int i = 0; i < childsToCompare.getLength(); i++) {
            Node aChild = childsToCompare.item(i);

            if (aChild != childToFind) {
                NamedNodeMap childAttributes = aChild.getAttributes();
                if (childAttributes != null && childAttributes.getLength() > 0) {
                    for (int j = 0; j < childAttributes.getLength(); j++) {
                        String nameTemp = childAttributes.item(j).getNodeName();
                        String valueTemp = childAttributes.item(j).getNodeValue();
                        String[] nameSplit = nameTemp.split(":");

                        if (nameSplit.length >= 2 && nameSplit[0].toLowerCase().equals("rdf")) {
                            if(valueTemp.equals(value)){
                                return (new ChildContained(true, value, aChild.getParentNode()));
                            }
                        }
                    }
                }
            }
        }
        
        return (new ChildContained(false, value, childToFind.getParentNode()));
    }
}
